logo头像
Snippet 博客主题

android Flutter 8.数据存储-File

本文于375天之前发表,文中内容可能已经过时。

android Flutter 8.数据存储-File

为了将文件保存到磁盘,我们需要将 path_provider 插件与dart:io 库结合起来 。

  • 1.找到正确的本地路径
  • 2.创建对文件位置的引用
  • 3.将数据写入文件
  • 4.从文件中读取数据

1.找到正确的本地路径

path_provider插件提供了一种平台不可知的方式来访问设备文件系统上的常用位置。该插件当前支持访问两个文件系统位置:

临时目录(Temporary directory):系统可随时清除的临时目录(缓存)。
在iOS上,这对应于NSTemporaryDirectory() 返回的值 。
在Android上,这是getCacheDir() 返回的值。

文档目录(Documents directory):应用程序的目录,用于存储只有它可以访问的文件。只有当应用程序被删除时,系统才会清除目录。
在iOS上,这对应于NSDocumentDirectory。
在Android上,这是 AppData目录。

在我们的例子中,我们希望将信息存储在文档目录中!我们可以像这样找到文档目录的路径:

1
2
3
4
5
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();

return directory.path;
}

2.创建对文件位置的引用

一旦我们知道在哪里存储文件,我们需要创建一个文件的完整位置的引用。我们可以使用File 类从 dart:io 库来实现这一目标。

1
2
3
4
Future<File> get _localFile async {
final path = await _localPath;
return new File('$path/counter.txt');
}

3.将数据写入文件

现在我们有了一个File合作关系,我们可以使用它来读取和写入数据!首先,我们将一些数据写入文件。由于我们正在使用计数器,因此我们只会将整数存储为字符串。

1
2
3
4
5
6
Future<File> writeCounter(int counter) async {
final file = await _localFile;

// Write the file
return file.writeAsString('$counter');
}

4.从文件中读取数据

现在我们在磁盘上有一些数据,我们可以阅读它!我们再次使用这个 File类来做到这一点。

1
2
3
4
5
6
7
8
9
10
11
12
13
Future<int> readCounter() async {
try {
final file = await _localFile;

// Read the file
String contents = await file.readAsString();

return int.parse(contents);
} catch (e) {
// If we encounter an error, return 0
return 0;
}
}

测试

为了测试与文件交互的代码,我们需要模拟调用MethodChannel。这MethodChannel是Flutter用来与主机平台进行通信的类。

在我们的测试中,我们无法与设备上的文件系统进行交互。我们需要与我们的测试环境的文件系统进行交互!

为了模拟方法调用,我们可以setupAll在我们的测试文件中提供一个函数。该功能将在测试执行之前运行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
setUpAll(() async {
// Create a temporary directory to work with
final directory = await Directory.systemTemp.createTemp();

// Mock out the MethodChannel for the path_provider plugin
const MethodChannel('plugins.flutter.io/path_provider')
.setMockMethodCallHandler((MethodCall methodCall) async {
// If we're getting the apps documents directory, return the path to the
// temp directory on our test environment instead.
if (methodCall.method == 'getApplicationDocumentsDirectory') {
return directory.path;
}
return null;
});
});

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import 'dart:async';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';

void main() {
runApp(
new MaterialApp(
title: 'Reading and Writing Files',
home: new FlutterDemo(storage: new CounterStorage()),
),
);
}

class CounterStorage {
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();

return directory.path;
}

Future<File> get _localFile async {
final path = await _localPath;
return new File('$path/counter.txt');
}

Future<int> readCounter() async {
try {
final file = await _localFile;

// Read the file
String contents = await file.readAsString();

return int.parse(contents);
} catch (e) {
// If we encounter an error, return 0
return 0;
}
}

Future<File> writeCounter(int counter) async {
final file = await _localFile;

// Write the file
return file.writeAsString('$counter');
}
}

class FlutterDemo extends StatefulWidget {
final CounterStorage storage;

FlutterDemo({Key key, @required this.storage}) : super(key: key);

@override
_FlutterDemoState createState() => new _FlutterDemoState();
}

class _FlutterDemoState extends State<FlutterDemo> {
int _counter;

@override
void initState() {
super.initState();
widget.storage.readCounter().then((int value) {
setState(() {
_counter = value;
});
});
}

Future<File> _incrementCounter() async {
setState(() {
_counter++;
});

// write the variable as a string to the file
return widget.storage.writeCounter(_counter);
}

@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text('Reading and Writing Files')),
body: new Center(
child: new Text(
'Button tapped $_counter time${_counter == 1 ? '' : 's'}.',
),
),
floatingActionButton: new FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: new Icon(Icons.add),
),
);
}
}
支付宝打赏 微信打赏

打赏